home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / misc / TownMaze.lha / TownMaze / src.lzh / connectst.c < prev    next >
C/C++ Source or Header  |  1991-08-04  |  5KB  |  176 lines

  1. /*
  2. ** connectst.c  Copyright 1991 Kent Paul Dolan,
  3. **              Mountain View, CA, USA 94039-0755
  4. **
  5. ** Written to satisfy an inquiry on USENet's rec.games.programmer newsgroup.
  6. ** May be freely used or modified in any non-commercial work.  Copyrighted
  7. ** only to prevent patenting by someone else.
  8. */
  9.  
  10. #include <stdio.h>
  11. #include "townmaze.h"
  12. #include "townproto.h"
  13.  
  14. #ifdef __STDC__
  15. void connectstreets()
  16. #else
  17. int connectstreets()
  18. #endif
  19. {
  20.   int targetcell;
  21.   int livewalk, i;
  22.   int deadwalk, lastdead, j, k;
  23.   int cheapdir;
  24.   int nhbrid;
  25.  
  26. /*
  27. ** Sanity check; make sure we don't go spinning off with no work possible.
  28. */
  29.  
  30.   if (streetnumct < 1)
  31.   {
  32.     fprintf(stderr,"No streets seeded! Oops!  Logic bomb!\n");
  33.     freespace();
  34.     exit(1);
  35.   }
  36.  
  37. /*
  38. ** Three phase maneuver; phase 1, try to connect streets by using live
  39. ** cells to turn into street cells.
  40. */
  41.  
  42. #if PROGRESS
  43.   fprintf(stderr,"Streets 1 ");
  44. #endif
  45.  
  46.  
  47.   while((streetnumct > 1) && (livect > 0))
  48.   {
  49.     targetcell = RANDOM()%livect;
  50.     livewalk = live;
  51.     for (i = 0; i < (targetcell - 1); i++)
  52.       if (livewalk == NOPOINTER)
  53.       {
  54.         fprintf(stderr,"live list too short in connectstreets\n");
  55.         showdebugmaze();
  56.         freespace();
  57.         exit(1);
  58.       }
  59.       else
  60.       {
  61.         livewalk = statlist[livewalk].next;
  62.       }
  63. /*
  64. ** Since this is a live cell, it is supposed to have a street cell
  65. ** neighbor; find one and adopt its street number.  If directions
  66. ** are implemented, then this has to be expanded to pick a random
  67. ** neighbor street fairly and adopt its number and direction.
  68. ** [Done in makestreet(), instead, by the "-1" direction parameter..]
  69. */
  70.     for (nhbrid = 0; nhbrid < 4; nhbrid++)
  71.       if (nhbrexists(livewalk,nhbrid))
  72.         if (statlist[nhbris(livewalk,nhbrid)].status == STREET)
  73.         {
  74.           makestreet(livewalk,
  75.             statlist[nhbris(livewalk,nhbrid)].streetnum,-1);
  76.           break;
  77.         }
  78.   }
  79.  
  80. /*
  81. ** Phase 2: try for a cheap connect by only using dead cells between streets
  82. ** with different streetnums; this should get some more streets connected,
  83. ** without turning the whole map into streets.
  84. */
  85.  
  86.   if ((streetnumct > 1) && (deadct > 0))
  87.   {
  88.  
  89. #if PROGRESS
  90.   fprintf(stderr,"Streets 2 ");
  91. #endif
  92.  
  93.     deadwalk = dead;
  94.     for (i = 0; i < deadct; i++)
  95.     {
  96.       if (deadwalk == NOPOINTER) break;
  97.       if (streetnumct <= 1) break;
  98.       lastdead = deadwalk;
  99.       deadwalk = statlist[deadwalk].next;
  100.       if (interiorcell(lastdead))
  101.       {
  102.         for (j = 0; j < 4; j++)
  103.           if (nhbrexists(lastdead,j))
  104.             for (k = 0; k < 4; k++)
  105.             {
  106.               if (j == k) continue;
  107.               if (nhbrexists(lastdead,k))
  108. /*
  109. ** The reason this loop doesn't keep trying to make a street out of the
  110. ** chosen cell after it has done so once is that makestreet() causes
  111. ** all the adjacent streets to be merged and have the same street number,
  112. ** so that the next if always fails after the first success.  It can thus
  113. ** safely be let run to completion.
  114. */
  115.                 if (   (statlist[nhbris(lastdead,j)].status == STREET)
  116.                     && (statlist[nhbris(lastdead,k)].status == STREET)
  117.                     && (statlist[nhbris(lastdead,j)].streetnum
  118.                         != statlist[nhbris(lastdead,k)].streetnum)
  119.                    )
  120.                 {
  121.                   cheapdir = ((j+2)%4);
  122.                   if (statlist[nhbris(lastdead,k)].streetdir == ((k+2)%4))
  123.                     cheapdir = ((k+2)%4); 
  124.                   makestreet(lastdead,statlist[nhbris(lastdead,j)].streetnum,
  125.                              cheapdir);
  126.                 }
  127.             }
  128.       }
  129.       
  130.     }
  131.   }
  132.  
  133. /*
  134. ** Phase 3: when out of luck, use brute force (haven't ever seen this
  135. ** required, but can't prove it isn't)..
  136. */
  137.  
  138. #if PROGRESS
  139.   if (streetnumct > 1) fprintf(stderr,"Streets 3 ");
  140. #endif
  141.  
  142.   while((streetnumct > 1) && (deadct > 0))
  143.   {
  144.     targetcell = RANDOM()%deadct;
  145.     deadwalk = dead;
  146.     for (i = 0; i < (targetcell - 1); i++)
  147.       if (deadwalk == NOPOINTER)
  148.       {
  149.         fprintf(stderr,"dead list too short in connectstreets\n");
  150.         showdebugmaze();
  151.         freespace();
  152.         exit(1);
  153.       }
  154.       else
  155.       {
  156.         deadwalk = statlist[deadwalk].next;
  157.       }
  158. /*
  159. ** Since this is a dead cell, it is necessary to check that it is an interior
  160. ** one.  This should again be enhanced when directions are installed.
  161. */
  162.     if (interiorcell(deadwalk))
  163.     {
  164.       for (nhbrid = 0; nhbrid < 4; nhbrid++)
  165.         if (nhbrexists(deadwalk,nhbrid))
  166.           if (statlist[nhbris(deadwalk,nhbrid)].status == STREET)
  167.           {
  168.             makestreet(deadwalk,
  169.               statlist[nhbris(deadwalk,nhbrid)].streetnum,-1);
  170.             break;
  171.           }
  172.     }
  173.   }
  174.  
  175. }
  176.